/* Copyright 2009 Sony Mathew, Minneapolis MN. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at  http://www.apache.org/licenses/LICENSE-2.0  Unless required by applicable law or agreed to in writing, software  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */
package com.xsm.muck.gwt.client;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.xsm.gwt.widgets.client.AxisPanel;
import com.xsm.gwt.widgets.client.AxisPanel2DemoPanel;
import com.xsm.gwt.widgets.client.AxisPanelDemoPanel;
import com.xsm.gwt.widgets.client.AxisTableDemoPanel;
import com.xsm.gwt.widgets.client.BrowserType;
import com.xsm.gwt.widgets.client.CustomPanel;
import com.xsm.gwt.widgets.client.HTMLIncludePanel;
import com.xsm.gwt.widgets.client.MinSizePanel;
import com.xsm.muck.gwt.client.msgs.FoodMessages;

/**
 * This is the Panel of interest: Contains sample usages of various concepts.
 * 
 * @author Sony Mathew
 */
public class MuckTestSuitePanel extends CustomPanel {

    /**
     * My IoC dependencies.
     */
    public interface Context extends CustomPanel.Context {      
        public Panel getChatPanel();  
    }

    private final Context cxt;
    
    /**
     * author Sony Mathew
     */
    public MuckTestSuitePanel(Context cxt) {
        super(cxt);
        this.cxt = cxt;
    }
    
    /**
     * author Sony Mathew
     */
    public MuckTestSuitePanel build() {        
        AxisPanel main = new AxisPanel().space(5);
        
        for(Panel testCasePanel : testCasePanels()) {
            main.x(testCasePanel).q();
        }        
        
        add(main);
        
        return this;
    }
    /**
     * Provide the TestCases as panels that have interactive ways to activate each test.
     * 
     * author Sony Mathew
     */
    public List<Panel> testCasePanels() {
        List<Panel> testCasePanels = new ArrayList<Panel>();
        
        //Add test case panels.
        testCasePanels.add(new MuckTestCaseBorderPanel().build("Test Sanity", testSanityPanel()));
        testCasePanels.add(new MuckTestCaseBorderPanel().build("Test Events", testEventsPanel()));
        testCasePanels.add(new MuckTestCaseBorderPanel().build("Test AxisPanel", new AxisPanelDemoPanel().build(300, 100)));
        testCasePanels.add(new MuckTestCaseBorderPanel().build("Test AxisPanel2", new AxisPanel2DemoPanel().build(300, 100)));
        testCasePanels.add(new MuckTestCaseBorderPanel().build("Test AxisTable 1", new AxisTableDemoPanel().buildRowByRowPlaceDirectDemo()));
        testCasePanels.add(new MuckTestCaseBorderPanel().build("Test AxisTable 2", new AxisTableDemoPanel().buildIndexCellPlaceDemo()));
        testCasePanels.add(new MuckTestCaseBorderPanel().build("Test AxisTable 3", new AxisTableDemoPanel().buildOverlayByIndexBoundsDemo()));
        testCasePanels.add(new MuckTestCaseBorderPanel().build("Test AxisTable 4", new AxisTableDemoPanel().buildOverlayByWidgetBoundsDemo()));
        testCasePanels.add(new MuckTestCaseBorderPanel().build("Test AxisTable 5 - TH Header", new AxisTableDemoPanel().buildWithTHHeader()));
        testCasePanels.add(new MuckTestCaseBorderPanel().build("Test MinSizePanel", testMinSizePanel()));
        testCasePanels.add(new MuckTestCaseBorderPanel().build("Test Messages", testMessagesPanel()));
        testCasePanels.add(new MuckTestCaseBorderPanel().build("Test HTML Include", testHTMLInclude()));
        testCasePanels.add(new MuckTestCaseBorderPanel().build("Test Images", testImages()));
        testCasePanels.add(new MuckTestCaseBorderPanel().build("Test Images Clipped", testImagesClipped()));
        testCasePanels.add(new MuckTestCaseBorderPanel().build("Test Images Clipped, Auto Refreshed", testImagesClippedAutoRefresh()));
        testCasePanels.add(new MuckTestCaseBorderPanel().build("Test Images Clipped, Manual Refreshed", testImagesClippedManualRefresh()));
        return testCasePanels;
    }
    
    /**
     * author Sony Mathew
     */
    public Panel testSanityPanel() {
        Button testBtn = new Button("Sanity");
        testBtn.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent e) {
                msg("testSanity", "BrowserType: [" + BrowserType.getBrowserType() + "]");
                msg("testSanity", "Sanity Check Successful");
            }            
        });
        return new AxisPanel().x(testBtn);
    }
    
    /**
     * Test events locally and remote RPCing.
     *
     * See ChatPanel who fires events locally when text is entered.
     * See MsgPanel who listens to these events locally and prints them to the Messages area.
     * 
     * Additionally, the events fired by the ChatPanel being Remote Events will get RPC's down to the server
     *  and processed by the registered processor (in this case: MuckRemoteControlImpl).
     *      and the response events coming back are handled by the MsgPanel as well.
     *       
     * author Sony Mathew
     */
    public Panel testEventsPanel() {
        return cxt.getChatPanel();
    }
              
    
    private void msg(String src, String msg) {
        fire(new MsgEvent(src, msg));
    }

    /**
     * Tests the MinSizePanel.
     * 
     * author Sony Mathew
     */
    public Panel testMinSizePanel() {
        SimplePanel contentPanel = new SimplePanel();
        contentPanel.setStyleName("testMinSizePanelContent");
        
        MinSizePanel minSizePanel = new MinSizePanel();
        minSizePanel.addStyleName("testMinSizePanel");
        minSizePanel.setHorizontalAlignment(HorizontalPanel.ALIGN_CENTER);
        minSizePanel.setVerticalAlignment(VerticalPanel.ALIGN_MIDDLE);
        minSizePanel.addMinWidthSizerStyleName("testMinSizePanelMinWidthSizer");
        minSizePanel.addMinHeightSizerStyleName("testMinSizePanelMinHeightSizer");
        
        minSizePanel.add(contentPanel);
        return minSizePanel;
    }
    
    /**
     * This just tests the resource bundle type utility offered by GWT. 
     */
    public Panel testMessagesPanel() {
        FoodMessages foodMsgs = (FoodMessages)GWT.create(FoodMessages.class);
        return new AxisPanel()
            .put(foodMsgs.breakfastSpecial("Steak", "Potatoes", "Asparagus", "Coffee or Juice"))
            .put(foodMsgs.breakfastSpecial("Chicken", "Rice", "Beans", "Pop or Juice"))
            ;
    }
    
    public Panel testHTMLInclude() {
        HTMLIncludePanel p = new HTMLIncludePanel("/test.htmx");
        p.refresh();
        setupJS();
        return p;
    }
    
    private native void setupJS() /*-{
        $wnd.test = new Object();
        $wnd.test.staticCallIntoGWT = @com.xsm.muck.gwt.client.MuckTestSuitePanel::testStaticCallIntoGWTImpl(Ljava/lang/String;);
        $wnd.test.instanceCallIntoGWT = this.@com.xsm.muck.gwt.client.MuckTestSuitePanel::testInstanceCallIntoGWTImpl(Ljava/lang/String;);
    }-*/;

    public static void testStaticCallIntoGWTImpl(String arg) {
        Window.alert("You have successfully invoked a static GWT method passing [" + arg + "]");
    }
    
    public void testInstanceCallIntoGWTImpl(String arg) {
        Window.alert("You have successfully invoked an instance GWT method passing [" + arg + "]");
    }
    
    /**
     * May cause IE8 mixed security warning?
     * 
     * author Sony Mathew
     */    
    public Panel testImages() {
        AxisPanel images = new AxisPanel().x();
        for(int i=0;i<10;i++) {
            images.put(new Image("arrow_right.gif"));
        }
        images.q();
        return images;
    }

    /**
     * May cause IE8 mixed security warning?
     * 
     * author Sony Mathew
     */    
    public Panel testImagesClipped() {
        AxisPanel images = new AxisPanel().x();
        for(int i=0;i<20;i++) {
            images.put(new Image("arrow_right.gif", 0, 0, i, i));
        }
        images.q();        
        return images;
    }

    /**
     * May cause IE8 mixed security warning?
     * 
     * author Sony Mathew
     */
    public Panel testImagesClippedAutoRefresh() {
        final SimplePanel imagesHolder = new SimplePanel();
        
        Timer imageTimer = new Timer() {
            int i = 0;
            @Override
            public void run() {
                if (i % 2 == 0) {
                    imagesHolder.setWidget(testImagesClipped());
                }else{
                    imagesHolder.setWidget(new Label("Refreshing..."));
                }
                i++;
            }            
        };
        
        imageTimer.scheduleRepeating(1000);
        return imagesHolder;
    }

    /**
     * May cause IE8 mixed security warning?
     * 
     * author Sony Mathew
     */
    public Panel testImagesClippedManualRefresh() {        
        final SimplePanel imagesHolder = new SimplePanel();
        imagesHolder.setWidget(testImagesClipped());
        
        final Button refreshBtn = new Button("Refresh");
        refreshBtn.addClickHandler(new ClickHandler() {
            int i = 1;
            public void onClick(ClickEvent event) {
                if (i % 2 == 0) {
                    imagesHolder.setWidget(testImagesClipped());
                }else{
                    imagesHolder.setWidget(new Label("Click again to Refresh"));
                }
                i++;
            }            
        });
        
        final AxisPanel manualTest = new AxisPanel().x()
            .put(imagesHolder)
            .put(refreshBtn);
                
        return manualTest;
    }
    
}
